লেগাসি কোড রিফ্যাক্টরিং করার একটি ব্যবহারিক নির্দেশিকা, যেখানে শনাক্তকরণ, অগ্রাধিকার প্রদান, কৌশল এবং আধুনিকীকরণ ও রক্ষণাবেক্ষণের জন্য সেরা অনুশীলনগুলি আলোচনা করা হয়েছে।
দানবকে বশে আনা: লেগাসি কোডের জন্য রিফ্যাক্টরিং কৌশল
লেগাসি কোড। এই শব্দটি শুনলেই প্রায়শই বিশাল, অ-নথিভুক্ত সিস্টেম, ভঙ্গুর নির্ভরতা এবং এক অপ্রতিরোধ্য ভয়ের ছবি ভেসে ওঠে। বিশ্বজুড়ে অনেক ডেভেলপার এই সিস্টেমগুলো রক্ষণাবেক্ষণ এবং উন্নত করার চ্যালেঞ্জের মুখোমুখি হন, যা প্রায়শই ব্যবসায়িক কার্যক্রমের জন্য অত্যন্ত গুরুত্বপূর্ণ। এই বিস্তারিত নির্দেশিকা লেগাসি কোড রিফ্যাক্টরিং করার জন্য ব্যবহারিক কৌশল সরবরাহ করে, যা একটি হতাশার উৎসকে আধুনিকীকরণ এবং উন্নতির সুযোগে পরিণত করতে পারে।
লেগাসি কোড কী?
রিফ্যাক্টরিং কৌশলগুলিতে যাওয়ার আগে, "লেগাসি কোড" বলতে আমরা কী বুঝি তা সংজ্ঞায়িত করা অপরিহার্য। যদিও এই শব্দটি কেবল পুরানো কোডকে বোঝাতে পারে, এর একটি সূক্ষ্ম সংজ্ঞা এর রক্ষণাবেক্ষণের ক্ষমতার উপর আলোকপাত করে। মাইকেল ফেদারস তার বিখ্যাত বই "ওয়ার্কিং এফেক্টিভলি উইথ লেগাসি কোড"-এ লেগাসি কোডকে টেস্ট ছাড়া কোড হিসাবে সংজ্ঞায়িত করেছেন। টেস্টের এই অভাব রিগ্রেশন তৈরি না করে কোডকে নিরাপদে পরিবর্তন করা কঠিন করে তোলে। তবে, লেগাসি কোডের অন্যান্য বৈশিষ্ট্যও থাকতে পারে:
- ডকুমেন্টেশনের অভাব: মূল ডেভেলপাররা হয়তো চলে গেছেন, সিস্টেমের আর্কিটেকচার, ডিজাইনের সিদ্ধান্ত বা এমনকি মৌলিক কার্যকারিতা ব্যাখ্যা করে সামান্য বা কোনো ডকুমেন্টেশন রেখে যাননি।
- জটিল নির্ভরতা: কোডটি হয়তো শক্তভাবে সংযুক্ত (tightly coupled) থাকতে পারে, যার ফলে সিস্টেমের অন্যান্য অংশকে প্রভাবিত না করে পৃথক উপাদানগুলিকে আলাদা করা এবং পরিবর্তন করা কঠিন হয়ে পড়ে।
- পুরানো প্রযুক্তি: কোডটি হয়তো পুরানো প্রোগ্রামিং ভাষা, ফ্রেমওয়ার্ক বা লাইব্রেরি ব্যবহার করে লেখা হতে পারে যা আর সক্রিয়ভাবে সমর্থিত নয়, যা নিরাপত্তা ঝুঁকি তৈরি করে এবং আধুনিক সরঞ্জাম ব্যবহারের সুযোগ সীমিত করে।
- দুর্বল কোডের মান: কোডে ডুপ্লিকেট কোড, লম্বা মেথড এবং অন্যান্য কোড স্মেল থাকতে পারে যা এটি বোঝা এবং রক্ষণাবেক্ষণ করা কঠিন করে তোলে।
- ভঙ্গুর ডিজাইন: আপাতদৃষ্টিতে ছোট পরিবর্তনগুলির অপ্রত্যাশিত এবং ব্যাপক পরিণতি হতে পারে।
এটা মনে রাখা গুরুত্বপূর্ণ যে লেগাসি কোড সহজাতভাবে খারাপ নয়। এটি প্রায়শই একটি উল্লেখযোগ্য বিনিয়োগের প্রতিনিধিত্ব করে এবং মূল্যবান ডোমেইন জ্ঞান ধারণ করে। রিফ্যাক্টরিংয়ের লক্ষ্য হলো এই মান সংরক্ষণ করার পাশাপাশি কোডের রক্ষণাবেক্ষণযোগ্যতা, নির্ভরযোগ্যতা এবং কর্মক্ষমতা উন্নত করা।
কেন লেগাসি কোড রিফ্যাক্টর করবেন?
লেগাসি কোড রিফ্যাক্টর করা একটি কঠিন কাজ হতে পারে, তবে এর সুবিধাগুলো প্রায়শই চ্যালেঞ্জগুলোকে ছাড়িয়ে যায়। রিফ্যাক্টরিংয়ে বিনিয়োগ করার কিছু মূল কারণ এখানে দেওয়া হলো:
- উন্নত রক্ষণাবেক্ষণযোগ্যতা: রিফ্যাক্টরিং কোডকে বোঝা, পরিবর্তন করা এবং ডিবাগ করা সহজ করে তোলে, যা চলমান রক্ষণাবেক্ষণের জন্য প্রয়োজনীয় খরচ এবং প্রচেষ্টা হ্রাস করে। বিশ্বব্যাপী দলগুলির জন্য এটি বিশেষভাবে গুরুত্বপূর্ণ, কারণ এটি নির্দিষ্ট ব্যক্তির উপর নির্ভরতা কমায় এবং জ্ঞান ভাগাভাগি করতে উৎসাহিত করে।
- টেকনিক্যাল ডেট হ্রাস: টেকনিক্যাল ডেট বলতে বোঝায় একটি সহজ সমাধান বেছে নেওয়ার কারণে পুনরায় কাজ করার অন্তর্নিহিত খরচ, যা দীর্ঘমেয়াদী ভালো পদ্ধতির চেয়ে দ্রুত সম্পন্ন হয়। রিফ্যাক্টরিং এই ঋণ পরিশোধ করতে সাহায্য করে, কোডবেসের সামগ্রিক স্বাস্থ্য উন্নত করে।
- বর্ধিত নির্ভরযোগ্যতা: কোড স্মেল মোকাবেলা করে এবং কোডের কাঠামো উন্নত করে, রিফ্যাক্টরিং বাগের ঝুঁকি কমাতে পারে এবং সিস্টেমের সামগ্রিক নির্ভরযোগ্যতা উন্নত করতে পারে।
- কর্মক্ষমতা বৃদ্ধি: রিফ্যাক্টরিং কর্মক্ষমতার বাধাগুলি সনাক্ত এবং সমাধান করতে পারে, যার ফলে দ্রুত এক্সিকিউশন সময় এবং উন্নত প্রতিক্রিয়াশীলতা পাওয়া যায়।
- সহজ ইন্টিগ্রেশন: রিফ্যাক্টরিং লেগাসি সিস্টেমকে নতুন সিস্টেম এবং প্রযুক্তির সাথে একীভূত করা সহজ করে তুলতে পারে, যা উদ্ভাবন এবং আধুনিকীকরণকে সক্ষম করে। উদাহরণস্বরূপ, একটি ইউরোপীয় ই-কমার্স প্ল্যাটফর্মকে একটি নতুন পেমেন্ট গেটওয়ের সাথে একীভূত করার প্রয়োজন হতে পারে যা একটি ভিন্ন এপিআই (API) ব্যবহার করে।
- ডেভেলপারদের মনোবল বৃদ্ধি: পরিষ্কার, সুগঠিত কোডের সাথে কাজ করা ডেভেলপারদের জন্য আরও আনন্দদায়ক এবং উৎপাদনশীল। রিফ্যাক্টরিং মনোবল বাড়াতে এবং প্রতিভা আকর্ষণ করতে পারে।
রিফ্যাক্টরিংয়ের জন্য উপযুক্ত কোড শনাক্তকরণ
সব লেগাসি কোড রিফ্যাক্টর করার প্রয়োজন হয় না। নিম্নলিখিত কারণগুলির উপর ভিত্তি করে রিফ্যাক্টরিং প্রচেষ্টাগুলিকে অগ্রাধিকার দেওয়া গুরুত্বপূর্ণ:
- পরিবর্তনের ফ্রিকোয়েন্সি: যে কোড ঘন ঘন পরিবর্তন করা হয় তা রিফ্যাক্টরিংয়ের জন্য একটি প্রধান প্রার্থী, কারণ রক্ষণাবেক্ষণযোগ্যতার উন্নতি উন্নয়ন উৎপাদনশীলতার উপর একটি উল্লেখযোগ্য প্রভাব ফেলবে।
- জটিলতা: যে কোড জটিল এবং বোঝা কঠিন, তাতে বাগ থাকার সম্ভাবনা বেশি এবং নিরাপদে পরিবর্তন করা কঠিন।
- বাগের প্রভাব: যে কোড ব্যবসায়িক কার্যক্রমের জন্য গুরুত্বপূর্ণ বা যা ব্যয়বহুল ত্রুটির উচ্চ ঝুঁকি বহন করে, সেটিকে রিফ্যাক্টরিংয়ের জন্য অগ্রাধিকার দেওয়া উচিত।
- কর্মক্ষমতার বাধা: যে কোডকে কর্মক্ষমতার বাধা হিসাবে চিহ্নিত করা হয়, সেটি কর্মক্ষমতা উন্নত করার জন্য রিফ্যাক্টর করা উচিত।
- কোড স্মেল: লম্বা মেথড, বড় ক্লাস, ডুপ্লিকেট কোড এবং ফিচার এনভির মতো সাধারণ কোড স্মেলগুলির উপর নজর রাখুন। এগুলি এমন ক্ষেত্রগুলির সূচক যা রিফ্যাক্টরিং থেকে উপকৃত হতে পারে।
উদাহরণ: একটি বিশ্বব্যাপী লজিস্টিকস কোম্পানির কথা ভাবুন যার চালান পরিচালনার জন্য একটি লেগাসি সিস্টেম রয়েছে। শিপিং খরচ গণনা করার জন্য দায়ী মডিউলটি পরিবর্তনশীল নিয়ম এবং জ্বালানির দামের কারণে ঘন ঘন আপডেট করা হয়। এই মডিউলটি রিফ্যাক্টরিংয়ের জন্য একটি প্রধান প্রার্থী।
রিফ্যাক্টরিং কৌশল
অনেক রিফ্যাক্টরিং কৌশল উপলব্ধ আছে, যার প্রতিটি নির্দিষ্ট কোড স্মেল মোকাবেলা করতে বা কোডের নির্দিষ্ট দিক উন্নত করার জন্য ডিজাইন করা হয়েছে। এখানে কিছু সাধারণভাবে ব্যবহৃত কৌশল রয়েছে:
মেথড কম্পোজ করা
এই কৌশলগুলি বড়, জটিল মেথডগুলিকে ছোট, আরও পরিচালনাযোগ্য মেথডে বিভক্ত করার উপর মনোযোগ দেয়। এটি পঠনযোগ্যতা উন্নত করে, পুনরাবৃত্তি হ্রাস করে এবং কোডকে পরীক্ষা করা সহজ করে তোলে।
- এক্সট্র্যাক্ট মেথড (Extract Method): এটি একটি নির্দিষ্ট কাজ সম্পাদন করে এমন একটি কোড ব্লক সনাক্ত করা এবং এটিকে একটি নতুন মেথডে স্থানান্তরিত করা জড়িত।
- ইনলাইন মেথড (Inline Method): এটি একটি মেথড কলকে মেথডের বডি দিয়ে প্রতিস্থাপন করা জড়িত। এটি ব্যবহার করুন যখন একটি মেথডের নাম তার বডির মতোই স্পষ্ট, অথবা যখন আপনি এক্সট্র্যাক্ট মেথড ব্যবহার করতে যাচ্ছেন কিন্তু বিদ্যমান মেথডটি খুব ছোট।
- রিপ্লেস টেম্প উইথ কোয়েরি (Replace Temp with Query): এটি একটি অস্থায়ী ভেরিয়েবলকে একটি মেথড কল দিয়ে প্রতিস্থাপন করা জড়িত যা প্রয়োজনে ভেরিয়েবলের মান গণনা করে।
- ইন্ট্রোডিউস এক্সপ্লেইনিং ভেরিয়েবল (Introduce Explaining Variable): একটি বর্ণনামূলক নামের ভেরিয়েবলে কোনো এক্সপ্রেশনের ফলাফল অ্যাসাইন করতে এটি ব্যবহার করুন, যা তার উদ্দেশ্য স্পষ্ট করে।
অবজেক্টগুলির মধ্যে ফিচার সরানো
এই কৌশলগুলি ক্লাস এবং অবজেক্টগুলির ডিজাইন উন্নত করার উপর মনোযোগ দেয়, দায়িত্বগুলিকে তাদের সঠিক জায়গায় সরিয়ে নিয়ে।
- মুভ মেথড (Move Method): এটি একটি মেথডকে একটি ক্লাস থেকে অন্য ক্লাসে সরানো জড়িত যেখানে এটি যৌক্তিকভাবে অন্তর্গত।
- মুভ ফিল্ড (Move Field): এটি একটি ফিল্ডকে একটি ক্লাস থেকে অন্য ক্লাসে সরানো জড়িত যেখানে এটি যৌক্তিকভাবে অন্তর্গত।
- এক্সট্র্যাক্ট ক্লাস (Extract Class): এটি একটি বিদ্যমান ক্লাস থেকে নিষ্কাশিত একটি সুসংহত দায়িত্বের সেট থেকে একটি নতুন ক্লাস তৈরি করা জড়িত।
- ইনলাইন ক্লাস (Inline Class): যখন একটি ক্লাস তার অস্তিত্বকে ন্যায্যতা দেওয়ার জন্য যথেষ্ট কাজ করছে না, তখন এটিকে অন্য ক্লাসে সংকুচিত করতে এটি ব্যবহার করুন।
- হাইড ডেলিগেট (Hide Delegate): এটি ক্লায়েন্ট থেকে ডেলিগেশন লজিক লুকানোর জন্য সার্ভারে মেথড তৈরি করে, ক্লায়েন্ট এবং ডেলিগেটের মধ্যে কাপলিং হ্রাস করে।
- রিমুভ মিডল ম্যান (Remove Middle Man): যদি একটি ক্লাস তার প্রায় সমস্ত কাজ ডেলিগেট করে, তবে এটি মধ্যস্থতাকারীকে বাদ দিতে সহায়তা করে।
- ইন্ট্রোডিউস ফরেন মেথড (Introduce Foreign Method): ক্লায়েন্টকে এমন বৈশিষ্ট্য সরবরাহ করার জন্য একটি ক্লায়েন্ট ক্লাসে একটি মেথড যুক্ত করে যা वास्तवে একটি সার্ভার ক্লাস থেকে প্রয়োজন, কিন্তু অ্যাক্সেসের অভাব বা সার্ভার ক্লাসে পরিকল্পিত পরিবর্তনের কারণে পরিবর্তন করা যায় না।
- ইন্ট্রোডিউস লোকাল এক্সটেনশন (Introduce Local Extension): একটি নতুন ক্লাস তৈরি করে যা নতুন মেথড ধারণ করে। যখন আপনি ক্লাসের সোর্স নিয়ন্ত্রণ করেন না এবং সরাসরি আচরণ যোগ করতে পারেন না তখন এটি দরকারী।
ডেটা সংগঠিত করা
এই কৌশলগুলি ডেটা সংরক্ষণ এবং অ্যাক্সেস করার উপায় উন্নত করার উপর মনোযোগ দেয়, যা বোঝা এবং পরিবর্তন করা সহজ করে তোলে।
- রিপ্লেস ডেটা ভ্যালু উইথ অবজেক্ট (Replace Data Value with Object): এটি একটি সাধারণ ডেটা মানকে একটি অবজেক্ট দিয়ে প্রতিস্থাপন করা জড়িত যা সম্পর্কিত ডেটা এবং আচরণকে এনক্যাপসুলেট করে।
- চেঞ্জ ভ্যালু টু রেফারেন্স (Change Value to Reference): যখন একাধিক অবজেক্ট একই মান শেয়ার করে তখন এটি একটি ভ্যালু অবজেক্টকে একটি রেফারেন্স অবজেক্টে পরিবর্তন করে।
- চেঞ্জ ইউনিডিরেকশনাল অ্যাসোসিয়েশন টু বাইডিরেকশনাল (Change Unidirectional Association to Bidirectional): দুটি ক্লাসের মধ্যে একটি দ্বিমুখী লিঙ্ক তৈরি করে যেখানে কেবল একটি একমুখী লিঙ্ক বিদ্যমান।
- চেঞ্জ বাইডিরেকশনাল অ্যাসোসিয়েশন টু ইউনিডিরেকশনাল (Change Bidirectional Association to Unidirectional): একটি দ্বিমুখী সম্পর্ককে একমুখী করে অ্যাসোসিয়েশনকে সহজ করে।
- রিপ্লেস ম্যাজিক নাম্বার উইথ সিম্বলিক কনস্ট্যান্ট (Replace Magic Number with Symbolic Constant): এটি লিটারেল মানগুলিকে নামযুক্ত কনস্ট্যান্ট দিয়ে প্রতিস্থাপন করা জড়িত, যা কোড বোঝা এবং রক্ষণাবেক্ষণ করা সহজ করে তোলে।
- এনক্যাপসুলেট ফিল্ড (Encapsulate Field): ফিল্ড অ্যাক্সেস করার জন্য একটি গেটার এবং সেটার মেথড সরবরাহ করে।
- এনক্যাপসুলেট কালেকশন (Encapsulate Collection): নিশ্চিত করে যে সংগ্রহের সমস্ত পরিবর্তন মালিক ক্লাসের সাবধানে নিয়ন্ত্রিত মেথডগুলির মাধ্যমে ঘটে।
- রিপ্লেস রেকর্ড উইথ ডেটা ক্লাস (Replace Record with Data Class): রেকর্ডের কাঠামোর সাথে মিলে যাওয়া ফিল্ড এবং অ্যাক্সেসর মেথড সহ একটি নতুন ক্লাস তৈরি করে।
- রিপ্লেস টাইপ কোড উইথ ক্লাস (Replace Type Code with Class): যখন টাইপ কোডের সম্ভাব্য মানগুলির একটি সীমিত, পরিচিত সেট থাকে তখন একটি নতুন ক্লাস তৈরি করুন।
- রিপ্লেস টাইপ কোড উইথ সাবক্লাস (Replace Type Code with Subclasses): যখন টাইপ কোডের মান ক্লাসের আচরণকে প্রভাবিত করে।
- রিপ্লেস টাইপ কোড উইথ স্টেট/স্ট্র্যাটেজি (Replace Type Code with State/Strategy): যখন টাইপ কোডের মান ক্লাসের আচরণকে প্রভাবিত করে, কিন্তু সাবক্লাসিং উপযুক্ত নয়।
- রিপ্লেস সাবক্লাস উইথ ফিল্ডস (Replace Subclass with Fields): একটি সাবক্লাস সরিয়ে দেয় এবং সুপারক্লাসে সাবক্লাসের স্বতন্ত্র বৈশিষ্ট্যগুলির প্রতিনিধিত্বকারী ফিল্ড যুক্ত করে।
শর্তসাপেক্ষ এক্সপ্রেশন সহজ করা
শর্তসাপেক্ষ যুক্তি দ্রুত জট পাকিয়ে যেতে পারে। এই কৌশলগুলির লক্ষ্য হল স্পষ্ট করা এবং সহজ করা।
- ডিকম্পোজ কন্ডিশনাল (Decompose Conditional): এটি একটি জটিল শর্তসাপেক্ষ বিবৃতিকে ছোট, আরও পরিচালনাযোগ্য অংশে বিভক্ত করা জড়িত।
- কনসলিডেট কন্ডিশনাল এক্সপ্রেশন (Consolidate Conditional Expression): এটি একাধিক শর্তসাপেক্ষ বিবৃতিকে একটি একক, আরও সংক্ষিপ্ত বিবৃতিতে একত্রিত করা জড়িত।
- কনসলিডেট ডুপ্লিকেট কন্ডিশনাল ফ্র্যাগমেন্টস (Consolidate Duplicate Conditional Fragments): এটি শর্তসাপেক্ষ বিবৃতির একাধিক শাখায় ডুপ্লিকেট করা কোডকে শর্তসাপেক্ষের বাইরে সরানো জড়িত।
- রিমুভ কন্ট্রোল ফ্ল্যাগ (Remove Control Flag): যুক্তির প্রবাহ নিয়ন্ত্রণ করতে ব্যবহৃত বুলিয়ান ভেরিয়েবলগুলি দূর করুন।
- রিপ্লেস নেস্টেড কন্ডিশনাল উইথ গার্ড ক্লজেস (Replace Nested Conditional with Guard Clauses): সমস্ত বিশেষ কেস শীর্ষে রেখে এবং তাদের কোনোটি সত্য হলে প্রক্রিয়াকরণ বন্ধ করে কোডকে আরও পঠনযোগ্য করে তোলে।
- রিপ্লেস কন্ডিশনাল উইথ পলিমরফিজম (Replace Conditional with Polymorphism): এটি শর্তসাপেক্ষ যুক্তিকে পলিমরফিজম দিয়ে প্রতিস্থাপন করা জড়িত, যা বিভিন্ন অবজেক্টকে বিভিন্ন কেস পরিচালনা করার অনুমতি দেয়।
- ইন্ট্রোডিউস নাল অবজেক্ট (Introduce Null Object): একটি নাল মানের জন্য পরীক্ষা করার পরিবর্তে, একটি ডিফল্ট অবজেক্ট তৈরি করুন যা ডিফল্ট আচরণ সরবরাহ করে।
- ইন্ট্রোডিউস অ্যাসারশন (Introduce Assertion): প্রত্যাশাগুলি পরীক্ষা করার জন্য একটি টেস্ট তৈরি করে স্পষ্টভাবে প্রত্যাশাগুলি নথিভুক্ত করুন।
মেথড কল সহজ করা
- রিনেম মেথড (Rename Method): এটি সুস্পষ্ট মনে হলেও, কোডকে পরিষ্কার করতে এটি অবিশ্বাস্যভাবে সহায়ক।
- অ্যাড প্যারামিটার (Add Parameter): একটি মেথড সিগনেচারে তথ্য যোগ করলে মেথডটি আরও নমনীয় এবং পুনঃব্যবহারযোগ্য হয়।
- রিমুভ প্যারামিটার (Remove Parameter): যদি একটি প্যারামিটার ব্যবহার না করা হয়, তবে ইন্টারফেসটি সহজ করার জন্য এটি থেকে মুক্তি পান।
- সেপারেট কোয়েরি ফ্রম মডিফায়ার (Separate Query from Modifier): যদি একটি মেথড একটি মান পরিবর্তন করে এবং ফেরত দেয়, তবে এটিকে দুটি পৃথক মেথডে বিভক্ত করুন।
- প্যারামিটারাইজ মেথড (Parameterize Method): অনুরূপ মেথডগুলিকে একটি একক মেথডে একত্রিত করতে এটি ব্যবহার করুন যেখানে একটি প্যারামিটার আচরণ পরিবর্তন করে।
- রিপ্লেস প্যারামিটার উইথ এক্সপ্লিসিট মেথডস (Replace Parameter with Explicit Methods): প্যারামিটারাইজের বিপরীতটি করুন - একটি একক মেথডকে একাধিক মেথডে বিভক্ত করুন যা প্রতিটি প্যারামিটারের একটি নির্দিষ্ট মান উপস্থাপন করে।
- প্রিজার্ভ হোল অবজেক্ট (Preserve Whole Object): একটি মেথডে কয়েকটি নির্দিষ্ট ডেটা আইটেম পাস করার পরিবর্তে, পুরো অবজেক্টটি পাস করুন যাতে মেথডটি তার সমস্ত ডেটা অ্যাক্সেস করতে পারে।
- রিপ্লেস প্যারামিটার উইথ মেথড (Replace Parameter with Method): যদি একটি মেথড সর্বদা একটি ফিল্ড থেকে প্রাপ্ত একই মান দিয়ে কল করা হয়, তবে মেথডের ভিতরে প্যারামিটার মানটি ডিরাইভ করার কথা বিবেচনা করুন।
- ইন্ট্রোডিউস প্যারামিটার অবজেক্ট (Introduce Parameter Object): যখন বেশ কয়েকটি প্যারামিটার স্বাভাবিকভাবে একসাথে থাকে তখন সেগুলিকে একটি অবজেক্টে গ্রুপ করুন।
- রিমুভ সেটিং মেথড (Remove Setting Method): যদি একটি ফিল্ড কেবল ইনিশিয়ালাইজ করা উচিত, কিন্তু নির্মাণের পরে পরিবর্তন করা উচিত নয়, তবে সেটার এড়িয়ে চলুন।
- হাইড মেথড (Hide Method): যদি একটি মেথড কেবল একটি একক ক্লাসের মধ্যে ব্যবহৃত হয় তবে তার দৃশ্যমানতা হ্রাস করুন।
- রিপ্লেস কনস্ট্রাক্টর উইথ ফ্যাক্টরি মেথড (Replace Constructor with Factory Method): কনস্ট্রাক্টরের একটি আরও বর্ণনামূলক বিকল্প।
- রিপ্লেস এক্সেপশন উইথ টেস্ট (Replace Exception with Test): যদি ব্যতিক্রমগুলি ফ্লো কন্ট্রোল হিসাবে ব্যবহার করা হয়, তবে কর্মক্ষমতা উন্নত করতে সেগুলিকে শর্তসাপেক্ষ যুক্তি দিয়ে প্রতিস্থাপন করুন।
সাধারণীকরণের সাথে মোকাবিলা
- পুল আপ ফিল্ড (Pull Up Field): একটি ফিল্ডকে একটি সাবক্লাস থেকে তার সুপারক্লাসে সরান।
- পুল আপ মেথড (Pull Up Method): একটি মেথডকে একটি সাবক্লাস থেকে তার সুপারক্লাসে সরান।
- পুল আপ কনস্ট্রাক্টর বডি (Pull Up Constructor Body): একটি কনস্ট্রাক্টরের বডি একটি সাবক্লাস থেকে তার সুপারক্লাসে সরান।
- পুশ ডাউন মেথড (Push Down Method): একটি মেথডকে একটি সুপারক্লাস থেকে তার সাবক্লাসগুলিতে সরান।
- পুশ ডাউন ফিল্ড (Push Down Field): একটি ফিল্ডকে একটি সুপারক্লাস থেকে তার সাবক্লাসগুলিতে সরান।
- এক্সট্র্যাক্ট ইন্টারফেস (Extract Interface): একটি ক্লাসের পাবলিক মেথডগুলি থেকে একটি ইন্টারফেস তৈরি করে।
- এক্সট্র্যাক্ট সুপারক্লাস (Extract Superclass): দুটি ক্লাস থেকে সাধারণ কার্যকারিতা একটি নতুন সুপারক্লাসে সরান।
- কলাপ্স হায়ারার্কি (Collapse Hierarchy): একটি সুপারক্লাস এবং সাবক্লাসকে একটি একক ক্লাসে একত্রিত করুন।
- ফর্ম টেমপ্লেট মেথড (Form Template Method): একটি সুপারক্লাসে একটি টেমপ্লেট মেথড তৈরি করুন যা একটি অ্যালগরিদমের ধাপগুলি সংজ্ঞায়িত করে, সাবক্লাসগুলিকে নির্দিষ্ট ধাপগুলি ওভাররাইড করার অনুমতি দেয়।
- রিপ্লেস ইনহেরিটেন্স উইথ ডেলিগেশন (Replace Inheritance with Delegation): কার্যকারিতা উত্তরাধিকার সূত্রে পাওয়ার পরিবর্তে, ক্লাসে কার্যকারিতা উল্লেখ করে একটি ফিল্ড তৈরি করুন।
- রিপ্লেস ডেলিগেশন উইথ ইনহেরিটেন্স (Replace Delegation with Inheritance): যখন ডেলিগেশন খুব জটিল হয়, তখন ইনহেরিটেন্সে স্যুইচ করুন।
এগুলি উপলব্ধ অনেক রিফ্যাক্টরিং কৌশলের কয়েকটি উদাহরণ মাত্র। কোন কৌশলটি ব্যবহার করা হবে তা নির্দিষ্ট কোড স্মেল এবং কাঙ্ক্ষিত ফলাফলের উপর নির্ভর করে।
উদাহরণ: একটি বিশ্বব্যাপী ব্যাংকের ব্যবহৃত জাভা অ্যাপ্লিকেশনের একটি বড় মেথড সুদের হার গণনা করে। ছোট, আরও ফোকাসড মেথড তৈরি করতে এক্সট্র্যাক্ট মেথড প্রয়োগ করলে পঠনযোগ্যতা উন্নত হয় এবং মেথডের অন্যান্য অংশকে প্রভাবিত না করে সুদের হার গণনার যুক্তি আপডেট করা সহজ হয়।
রিফ্যাক্টরিং প্রক্রিয়া
ঝুঁকি কমাতে এবং সাফল্যের সম্ভাবনা বাড়াতে রিফ্যাক্টরিং পদ্ধতিগতভাবে করা উচিত। এখানে একটি প্রস্তাবিত প্রক্রিয়া রয়েছে:
- রিফ্যাক্টরিং প্রার্থী শনাক্ত করুন: পূর্বে উল্লিখিত মানদণ্ড ব্যবহার করে কোডের এমন ক্ষেত্রগুলি শনাক্ত করুন যা রিফ্যাক্টরিং থেকে সবচেয়ে বেশি উপকৃত হবে।
- টেস্ট তৈরি করুন: কোনো পরিবর্তন করার আগে, কোডের বিদ্যমান আচরণ যাচাই করার জন্য স্বয়ংক্রিয় টেস্ট লিখুন। রিফ্যাক্টরিং যাতে রিগ্রেশন প্রবর্তন না করে তা নিশ্চিত করার জন্য এটি অত্যন্ত গুরুত্বপূর্ণ। ইউনিট টেস্ট লেখার জন্য JUnit (জাভা), pytest (পাইথন), বা Jest (জাভাস্ক্রিপ্ট) এর মতো টুল ব্যবহার করা যেতে পারে।
- ক্রমবর্ধমানভাবে রিফ্যাক্টর করুন: ছোট, ক্রমবর্ধমান পরিবর্তন করুন এবং প্রতিটি পরিবর্তনের পরে টেস্ট চালান। এটি যে কোনো ত্রুটি শনাক্ত করা এবং ঠিক করা সহজ করে তোলে।
- ঘন ঘন কমিট করুন: আপনার পরিবর্তনগুলি ঘন ঘন সংস্করণ নিয়ন্ত্রণে কমিট করুন। এটি আপনাকে কিছু ভুল হলে সহজেই পূর্ববর্তী সংস্করণে ফিরে যেতে দেয়।
- কোড পর্যালোচনা করুন: আপনার কোড অন্য একজন ডেভেলপার দ্বারা পর্যালোচনা করান। এটি সম্ভাব্য সমস্যা শনাক্ত করতে এবং রিফ্যাক্টরিং সঠিকভাবে করা হয়েছে কিনা তা নিশ্চিত করতে সহায়তা করতে পারে।
- কর্মক্ষমতা নিরীক্ষণ করুন: রিফ্যাক্টরিংয়ের পরে, সিস্টেমের কর্মক্ষমতা নিরীক্ষণ করুন যাতে পরিবর্তনগুলি কোনো কর্মক্ষমতা রিগ্রেশন প্রবর্তন না করে।
উদাহরণ: একটি দল একটি বিশ্বব্যাপী ই-কমার্স প্ল্যাটফর্মে একটি পাইথন মডিউল রিফ্যাক্টর করার সময় বিদ্যমান কার্যকারিতার জন্য ইউনিট টেস্ট তৈরি করতে `pytest` ব্যবহার করে। তারপরে তারা উদ্বেগকে পৃথক করতে এবং মডিউলের কাঠামো উন্নত করতে এক্সট্র্যাক্ট ক্লাস রিফ্যাক্টরিং প্রয়োগ করে। প্রতিটি ছোট পরিবর্তনের পরে, তারা কার্যকারিতা অপরিবর্তিত রয়েছে কিনা তা নিশ্চিত করতে টেস্ট চালায়।
লেগাসি কোডে টেস্ট যুক্ত করার কৌশল
মাইকেল ফেদারস যেমন যথার্থই বলেছেন, লেগাসি কোড হল টেস্ট ছাড়া কোড। বিদ্যমান কোডবেসে টেস্ট যুক্ত করা একটি বিশাল উদ্যোগ বলে মনে হতে পারে, তবে নিরাপদ রিফ্যাক্টরিংয়ের জন্য এটি অপরিহার্য। এই কাজটি করার জন্য এখানে বেশ কয়েকটি কৌশল রয়েছে:
ক্যারেক্টারাইজেশন টেস্ট (গোল্ডেন মাস্টার টেস্ট নামেও পরিচিত)
যখন আপনি এমন কোডের সাথে কাজ করছেন যা বোঝা কঠিন, তখন ক্যারেক্টারাইজেশন টেস্ট আপনাকে পরিবর্তন শুরু করার আগে এর বিদ্যমান আচরণ ক্যাপচার করতে সাহায্য করতে পারে। ধারণাটি হল এমন টেস্ট লেখা যা একটি নির্দিষ্ট ইনপুট সেটের জন্য কোডের বর্তমান আউটপুট নিশ্চিত করে। এই টেস্টগুলি অগত্যা সঠিকতা যাচাই করে না; তারা কেবল নথিভুক্ত করে যে কোডটি *বর্তমানে* কী করে।
পদক্ষেপ:
- আপনি যে কোডের ইউনিটটি চিহ্নিত করতে চান তা শনাক্ত করুন (যেমন, একটি ফাংশন বা মেথড)।
- একটি ইনপুট মানের সেট তৈরি করুন যা সাধারণ এবং এজ-কেস পরিস্থিতির একটি পরিসর প্রতিনিধিত্ব করে।
- সেই ইনপুটগুলির সাথে কোডটি চালান এবং ফলস্বরূপ আউটপুটগুলি ক্যাপচার করুন।
- এমন টেস্ট লিখুন যা নিশ্চিত করে যে কোডটি সেই ইনপুটগুলির জন্য সেই সঠিক আউটপুটগুলি তৈরি করে।
সতর্কতা: যদি অন্তর্নিহিত যুক্তি জটিল বা ডেটা-নির্ভর হয় তবে ক্যারেক্টারাইজেশন টেস্টগুলি ভঙ্গুর হতে পারে। যদি আপনাকে পরে কোডের আচরণ পরিবর্তন করতে হয় তবে সেগুলি আপডেট করার জন্য প্রস্তুত থাকুন।
স্প্রাউট মেথড এবং স্প্রাউট ক্লাস
এই কৌশলগুলি, যা মাইকেল ফেদারস দ্বারাও বর্ণিত হয়েছে, একটি লেগাসি সিস্টেমে নতুন কার্যকারিতা যুক্ত করার লক্ষ্য রাখে এবং বিদ্যমান কোড ভাঙার ঝুঁকি কমিয়ে দেয়।
স্প্রাউট মেথড: যখন আপনাকে একটি নতুন বৈশিষ্ট্য যোগ করতে হয় যার জন্য একটি বিদ্যমান মেথড পরিবর্তন করতে হয়, তখন একটি নতুন মেথড তৈরি করুন যাতে নতুন যুক্তি থাকে। তারপরে, বিদ্যমান মেথড থেকে এই নতুন মেথডটিকে কল করুন। এটি আপনাকে নতুন কোডটি আলাদা করতে এবং এটি স্বাধীনভাবে পরীক্ষা করতে দেয়।
স্প্রাউট ক্লাস: স্প্রাউট মেথডের মতো, কিন্তু ক্লাসের জন্য। একটি নতুন ক্লাস তৈরি করুন যা নতুন কার্যকারিতা বাস্তবায়ন করে, এবং তারপরে এটিকে বিদ্যমান সিস্টেমে একীভূত করুন।
স্যান্ডবক্সিং
স্যান্ডবক্সিংয়ের মধ্যে লেগাসি কোডকে সিস্টেমের বাকি অংশ থেকে আলাদা করা জড়িত, যা আপনাকে এটিকে একটি নিয়ন্ত্রিত পরিবেশে পরীক্ষা করার অনুমতি দেয়। এটি নির্ভরতার জন্য মক বা স্টাব তৈরি করে বা কোডটিকে একটি ভার্চুয়াল মেশিনে চালিয়ে করা যেতে পারে।
মিকাদো মেথড
মিকাদো মেথড হল জটিল রিফ্যাক্টরিং কাজগুলি মোকাবেলার জন্য একটি ভিজ্যুয়াল সমস্যা-সমাধান পদ্ধতি। এটি একটি ডায়াগ্রাম তৈরি করা জড়িত যা কোডের বিভিন্ন অংশের মধ্যে নির্ভরতা প্রতিনিধিত্ব করে এবং তারপরে এমনভাবে কোড রিফ্যাক্টর করা যা সিস্টেমের অন্যান্য অংশের উপর প্রভাব কমিয়ে দেয়। মূল নীতি হল পরিবর্তনটি "চেষ্টা" করা এবং দেখা যে কী ভেঙে যায়। যদি এটি ভেঙে যায়, তবে শেষ কার্যকরী অবস্থায় ফিরে যান এবং সমস্যাটি রেকর্ড করুন। তারপরে আসল পরিবর্তনটি পুনরায় চেষ্টা করার আগে সেই সমস্যাটি সমাধান করুন।
রিফ্যাক্টরিংয়ের জন্য টুলস
বেশ কিছু টুল রিফ্যাক্টরিংয়ে সহায়তা করতে পারে, পুনরাবৃত্তিমূলক কাজগুলি স্বয়ংক্রিয় করে এবং সেরা অনুশীলনগুলির বিষয়ে নির্দেশনা প্রদান করে। এই টুলগুলি প্রায়শই ইন্টিগ্রেটেড ডেভেলপমেন্ট এনভায়রনমেন্টে (IDEs) একীভূত থাকে:
- আইডিই (যেমন, IntelliJ IDEA, Eclipse, Visual Studio): আইডিইগুলি অন্তর্নির্মিত রিফ্যাক্টরিং টুল সরবরাহ করে যা স্বয়ংক্রিয়ভাবে ভেরিয়েবলের নাম পরিবর্তন, মেথড এক্সট্র্যাক্ট করা এবং ক্লাস সরানোর মতো কাজগুলি সম্পাদন করতে পারে।
- স্ট্যাটিক অ্যানালাইসিস টুলস (যেমন, SonarQube, Checkstyle, PMD): এই টুলগুলি কোড স্মেল, সম্ভাব্য বাগ এবং নিরাপত্তা দুর্বলতার জন্য কোড বিশ্লেষণ করে। তারা কোডের এমন ক্ষেত্রগুলি শনাক্ত করতে সাহায্য করতে পারে যা রিফ্যাক্টরিং থেকে উপকৃত হবে।
- কোড কভারেজ টুলস (যেমন, JaCoCo, Cobertura): এই টুলগুলি টেস্ট দ্বারা আচ্ছাদিত কোডের শতাংশ পরিমাপ করে। তারা কোডের এমন ক্ষেত্রগুলি শনাক্ত করতে সাহায্য করতে পারে যা পর্যাপ্তভাবে পরীক্ষা করা হয়নি।
- রিফ্যাক্টরিং ব্রাউজার (যেমন, Smalltalk Refactoring Browser): বিশেষায়িত টুল যা বড় পুনর্গঠন কার্যক্রমে সহায়তা করে।
উদাহরণ: একটি ডেভেলপমেন্ট টিম একটি বিশ্বব্যাপী বীমা কোম্পানির জন্য একটি C# অ্যাপ্লিকেশনে কাজ করছে এবং ভেরিয়েবলের নাম স্বয়ংক্রিয়ভাবে পরিবর্তন এবং মেথড এক্সট্র্যাক্ট করার জন্য Visual Studio-র অন্তর্নির্মিত রিফ্যাক্টরিং টুল ব্যবহার করে। তারা কোড স্মেল এবং সম্ভাব্য দুর্বলতা শনাক্ত করতে SonarQube ব্যবহার করে।
চ্যালেঞ্জ এবং ঝুঁকি
লেগাসি কোড রিফ্যাক্টরিং তার চ্যালেঞ্জ এবং ঝুঁকি ছাড়া হয় না:
- রিগ্রেশন প্রবর্তন: সবচেয়ে বড় ঝুঁকি হল রিফ্যাক্টরিং প্রক্রিয়া চলাকালীন বাগ প্রবর্তন করা। এটি ব্যাপক টেস্ট লিখে এবং ক্রমবর্ধমানভাবে রিফ্যাক্টর করে প্রশমিত করা যেতে পারে।
- ডোমেইন জ্ঞানের অভাব: যদি মূল ডেভেলপাররা চলে গিয়ে থাকেন, তবে কোড এবং এর উদ্দেশ্য বোঝা কঠিন হতে পারে। এটি ভুল রিফ্যাক্টরিং সিদ্ধান্তের দিকে নিয়ে যেতে পারে।
- টাইট কাপলিং: টাইটলি কাপলড কোড রিফ্যাক্টর করা আরও কঠিন, কারণ কোডের এক অংশে পরিবর্তন কোডের অন্যান্য অংশে অনিচ্ছাকৃত পরিণতি ঘটাতে পারে।
- সময়ের সীমাবদ্ধতা: রিফ্যাক্টরিংয়ে সময় লাগতে পারে, এবং স্টেকহোল্ডারদের কাছে বিনিয়োগকে ন্যায্যতা দেওয়া কঠিন হতে পারে যারা নতুন বৈশিষ্ট্য সরবরাহ করার উপর দৃষ্টি নিবদ্ধ করে।
- পরিবর্তনের প্রতিরোধ: কিছু ডেভেলপার রিফ্যাক্টরিংয়ের প্রতি প্রতিরোধী হতে পারে, বিশেষ করে যদি তারা জড়িত কৌশলগুলির সাথে পরিচিত না হয়।
সেরা অনুশীলন
লেগাসি কোড রিফ্যাক্টরিংয়ের সাথে সম্পর্কিত চ্যালেঞ্জ এবং ঝুঁকিগুলি প্রশমিত করতে, এই সেরা অনুশীলনগুলি অনুসরণ করুন:
- অনুমোদন পান: নিশ্চিত করুন যে স্টেকহোল্ডাররা রিফ্যাক্টরিংয়ের সুবিধাগুলি বোঝেন এবং প্রয়োজনীয় সময় এবং সংস্থান বিনিয়োগ করতে ইচ্ছুক।
- ছোট থেকে শুরু করুন: কোডের ছোট, বিচ্ছিন্ন অংশগুলি রিফ্যাক্টর করে শুরু করুন। এটি আত্মবিশ্বাস তৈরি করতে এবং রিফ্যাক্টরিংয়ের মূল্য প্রদর্শন করতে সহায়তা করবে।
- ক্রমবর্ধমানভাবে রিফ্যাক্টর করুন: ছোট, ক্রমবর্ধমান পরিবর্তন করুন এবং ঘন ঘন পরীক্ষা করুন। এটি যে কোনো ত্রুটি শনাক্ত করা এবং ঠিক করা সহজ করে তুলবে।
- টেস্ট স্বয়ংক্রিয় করুন: রিফ্যাক্টরিংয়ের আগে এবং পরে কোডের আচরণ যাচাই করার জন্য ব্যাপক স্বয়ংক্রিয় টেস্ট লিখুন।
- রিফ্যাক্টরিং টুল ব্যবহার করুন: পুনরাবৃত্তিমূলক কাজগুলি স্বয়ংক্রিয় করতে এবং সেরা অনুশীলনগুলির বিষয়ে নির্দেশনা প্রদান করতে আপনার আইডিই বা অন্যান্য টুলে উপলব্ধ রিফ্যাক্টরিং টুলগুলির সুবিধা নিন।
- আপনার পরিবর্তনগুলি নথিভুক্ত করুন: রিফ্যাক্টরিংয়ের সময় আপনি যে পরিবর্তনগুলি করেন তা নথিভুক্ত করুন। এটি অন্যান্য ডেভেলপারদের কোড বুঝতে এবং ভবিষ্যতে রিগ্রেশন প্রবর্তন এড়াতে সহায়তা করবে।
- অবিচ্ছিন্ন রিফ্যাক্টরিং: রিফ্যাক্টরিংকে একটি এককালীন ইভেন্টের পরিবর্তে উন্নয়ন প্রক্রিয়ার একটি অবিচ্ছিন্ন অংশ করুন। এটি কোডবেসকে পরিষ্কার এবং রক্ষণাবেক্ষণযোগ্য রাখতে সহায়তা করবে।
উপসংহার
লেগাসি কোড রিফ্যাক্টরিং একটি চ্যালেঞ্জিং কিন্তু ফলপ্রসূ প্রচেষ্টা। এই নির্দেশিকায় বর্ণিত কৌশল এবং সেরা অনুশীলনগুলি অনুসরণ করে, আপনি দানবকে বশে আনতে পারেন এবং আপনার লেগাসি সিস্টেমগুলিকে রক্ষণাবেক্ষণযোগ্য, নির্ভরযোগ্য এবং উচ্চ-কর্মক্ষম সম্পদে রূপান্তরিত করতে পারেন। পদ্ধতিগতভাবে রিফ্যাক্টরিংয়ের দিকে এগিয়ে যেতে, ঘন ঘন পরীক্ষা করতে এবং আপনার দলের সাথে কার্যকরভাবে যোগাযোগ করতে ভুলবেন না। সতর্ক পরিকল্পনা এবং সম্পাদনের মাধ্যমে, আপনি আপনার লেগাসি কোডের মধ্যে লুকিয়ে থাকা সম্ভাবনাকে আনলক করতে পারেন এবং ভবিষ্যতের উদ্ভাবনের জন্য পথ প্রশস্ত করতে পারেন।